from datetime import datetime
import json
from utils.datetime_my import custom_encoder_datetime


class CustomJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (int, float, str, bool, type(None))):
            return obj
        elif isinstance(obj, datetime):
            return custom_encoder_datetime(obj)
        elif isinstance(obj, dict):
            return {k: self.default(v) for k, v in obj.items()}
        elif isinstance(obj, (list, set, tuple)):
            return [self.default(i) for i in obj]
        elif hasattr(obj, '__dict__'):
            return self._encode_obj(obj)
        return str(obj)

    def _encode_obj(self, obj):
        # 防止无限递归的辅助方法
        if isinstance(obj, (int, float, str, bool, type(None), datetime)):
            return obj
        result = {}
        for k, v in obj.__dict__.items():
            if isinstance(v, (int, float, str, bool, type(None), datetime)):
                result[k] = v
            elif isinstance(v, (list, set, tuple)):
                result[k] = [self._encode_obj(i) for i in v]
            elif isinstance(v, dict):
                result[k] = {ik: self._encode_obj(iv) for ik, iv in v.items()}
            else:
                result[k] = self._encode_obj(v)
        return result

